package com.mzj.saas.mservice.oss.service;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.GetObjectRequest;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.StatusCode;
import com.mzj.saas.config.oss.OssConfig;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;

/**
 * 阿里云OSS对象存储
 *
 * @author shun
 * @createDate: 2021年3月23日 下午2:49:08
 * @version: 1.0
 *
 */
@Service
public class OSSService {
	private Logger LOG = LoggerFactory.getLogger(OSSService.class);
	@Autowired
	private OSSClient ossClient;
	@Autowired
	private OssConfig ossConfig;

	/**
	 * 上传文件
	 *
	 * @param bucketName
	 *            oss桶名称
	 *            文件
	 * @param type
	 *            文件业务类型
	 * @return 文件key
	 * @author shun
	 * @date 2021年3月24日
	 */
	public ResultBean<Object> putFile(String bucketName, MultipartFile mfile, String type) {
		long start = System.currentTimeMillis();
		ResultBean<Object> result = new ResultBean<>();
		if (StringUtils.isEmpty(bucketName)) {
			bucketName = ossConfig.getOssBucketName();
		}

		File temp = new File("temp_" + getNewName(mfile.getOriginalFilename()));
		StringBuilder fileKey = new StringBuilder();
		fileKey.append(type);
		fileKey.append("/").append(getNewName(mfile.getOriginalFilename()));
		try (FileOutputStream fos = new FileOutputStream(temp);
			 BufferedOutputStream bos = new BufferedOutputStream(fos)) {
			bos.write(mfile.getBytes());
			bos.flush();

			// 上传
			ossClient.putObject(bucketName, fileKey.toString(), temp);
			LOG.info("OSS success, path={} ,耗时:{}", fileKey.toString(), System.currentTimeMillis() - start);
			return ResultBean.successfulResult("https://xj-saas-images.oss-cn-qingdao.aliyuncs.com/"+fileKey.toString());
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
			result.setMsg(e.getMessage());
			return result;
		} finally {
			if (temp.exists()) {
				FileUtils.deleteQuietly(temp);
			}
		}
	}

	/**
	 * 上传文件
	 *
	 * @param bucketName
	 *            oss桶名称
	 * @param file
	 *            文件
	 * @param type
	 *            文件业务类型
	 * @return 文件key
	 * @author shun
	 * @date 2021年3月24日
	 */
	public String putFile(String bucketName, File file, String type) {
		try {
			StringBuilder fileKey = new StringBuilder();
			fileKey.append(type);
			fileKey.append("/").append(getNewName(file.getName()));
			// 上传
			ossClient.putObject(bucketName, fileKey.toString(), file);
			return fileKey.toString();
		} catch (Exception e) {
			LOG.info(e.getMessage(), e);
		}
		return null;
	}

	/**
	 * 返回文件访问全路径
	 *
	 * @param fileKey
	 * @return
	 * @author shun
	 * @date 2021年3月24日
	 */
	public String getOssFilePath(String fileKey) {
		//return ossConfig.getBucketUrl() + fileKey;
		return ossConfig.getBucketUrl();
	}

	/**
	 * 单文件删除
	 *
	 * @param bucketName
	 *            对象存储桶名称
	 * @param objectName
	 *            文件名称
	 * @author shun
	 * @date 2020年12月30日
	 */
	public ResultBean<Object> deleteObject(String bucketName, String fileKey) {
		LOG.info("OSSService deleteObject bucketName={},fileKey={}",bucketName,fileKey);
		ResultBean<Object> result = new ResultBean<>();
		if (StringUtils.isEmpty(bucketName)) {
			bucketName = ossConfig.getOssBucketName();
		}
		try {

			fileKey = URLDecoder.decode(fileKey,"UTF-8");
			if (fileKey.contains(ossConfig.getBucketUrl())) {
				String bucketUrl = ossConfig.getBucketUrl();
				fileKey = fileKey.substring(fileKey.indexOf(bucketUrl) + bucketUrl.length());
			}

			ossClient.deleteObject(bucketName, fileKey);
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
			result.setMsg(e.getMessage());
			return result;
		}

		return ResultBean.successfulResult(null);
	}

	/**
	 * 批量删除桶内所有对象
	 *
	 * @param bucketName
	 * @param keys
	 *            删除文件。key等同于ObjectName，表示删除OSS文件时需要指定包含文件后缀在内的完整路径，例如abc/efg/
	 *            123.jpg
	 * @return
	 * @author shun
	 * @date 2021年3月23日
	 */
	public List<String> batchDeleteObject(String bucketName, List<String> keys) {
		DeleteObjectsResult deleteObjectsResult = ossClient
				.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
		return deleteObjectsResult.getDeletedObjects();
	}

	private String getNewName(String filename) {
		int indx = filename.lastIndexOf(".");
		String suffix = filename.substring(indx, filename.length());
		return (getDate() + System.currentTimeMillis() + suffix);
	}

	private String getDate() {
		return DateFormatUtils.format(new Date(), "yyyyMMdd");
	}

	/**
	 * 下载文件
	 *
	 * @param bucketName
	 *            桶名称，可为空
	 * @param path
	 *            图片路径(不带HTTP与域名)
	 * @return
	 * @author shun
	 * @date 2021年10月27日
	 */
	public File getObjectFile(String bucketName, String path) {
		ResultBean<Object> result = new ResultBean<>();
		if (StringUtils.isEmpty(bucketName)) {
			bucketName = ossConfig.getOssBucketName();
		}

		File file = new File(ossConfig.getDownFileTempdir() + "temp_" + getNewName(path));
		//File file = new File("C:/files/" + "temp_" + getNewName(path));
		try {
			// 下载
			ossClient.getObject(new GetObjectRequest(bucketName, path), file);

			return file;
		} catch (Exception e) {
			LOG.error(e.getMessage(), e);
			result.setCode(StatusCode.ERROR_CODE_10001.getErrorCode());
			result.setMsg(e.getMessage());
			return null;
		}
	}
}
